package org.hs.phd.odi.bgsub.classification;

import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.List;

import org.hs.phd.odi.bgsub.vob.VisualObject;
import org.hs.phd.odi.bgsub.vob.VisualObjectClass;
import org.hs.phd.odi.transformation.ODITransformation;
import org.hs.phd.odi.transformation.ODIUtils;

import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class ODISimpleVehiclePersonClassifier implements VisualObjectClassifier {

	private static final double MIN_HEIGHT_TO_WIDTH_RATIO_VEHICLE = 0.1;

	private static final double MAX_HEIGHT_TO_WIDTH_RATIO_VEHICLE = 0.8;

	private static final double MAX_HEIGHT_TO_WIDTH_RATIO_HUMAN = 5;

	private static final double MIN_HEIGHT_TO_WIDTH_RATIO_HUMAN = 1.2;

	private static final int MIN_CLASSIFIABLE_OBJECT_SIZE = 50;
	
	private final ODITransformation transformation;

	public ODISimpleVehiclePersonClassifier(ODITransformation transformation) {
		this.transformation = transformation;
	}

	@Override
	public void classifyObjects(IplImage frameImage, List<VisualObject> fgObjects) {
		for(VisualObject obj : fgObjects){
			
			double area = getArea( obj.getPolygon() );
			if( area > MIN_CLASSIFIABLE_OBJECT_SIZE ){
				Rectangle2D.Double boundsOnTheSphere = ODIUtils.getBoundsOnTheSphere(transformation, obj.getPolygon());
				classifyObject(obj, boundsOnTheSphere);
			}else{
				obj.setObjectClass(VisualObjectClass.UNKNOWN);
			}
		}
	}
	
	public double getArea(Polygon p) {
		Rectangle bounds = p.getBounds();
		
		return bounds.width*bounds.height;
	}

	private void classifyObject(VisualObject obj, Rectangle2D.Double boundsOnTheSphere) {
		double thetaToPhiAspectRatio = boundsOnTheSphere.getWidth()/boundsOnTheSphere.getHeight();
		
		if(thetaToPhiAspectRatio > MIN_HEIGHT_TO_WIDTH_RATIO_HUMAN && thetaToPhiAspectRatio < MAX_HEIGHT_TO_WIDTH_RATIO_HUMAN ){
			obj.setObjectClass(VisualObjectClass.PERSON);
		}else if(thetaToPhiAspectRatio > MIN_HEIGHT_TO_WIDTH_RATIO_VEHICLE && thetaToPhiAspectRatio < MAX_HEIGHT_TO_WIDTH_RATIO_VEHICLE ){
			obj.setObjectClass(VisualObjectClass.VEHICLE);
		}else{
			obj.setObjectClass(VisualObjectClass.UNKNOWN);
		}
	}

}
